package 简单.字符串;

import java.util.HashMap;
import java.util.Map;

/**
 * 给你两个字符串 s 和 goal ，只要我们可以通过交换 s 中的两个字母得到与 goal 相等的结果，就返回 true ；否则返回 false 。
 * <p>
 * 交换字母的定义是：取两个下标 i 和 j （下标从 0 开始）且满足 i != j ，接着交换 s[i] 和 s[j] 处的字符。
 * <p>
 * 例如，在 "abcd" 中交换下标 0 和下标 2 的元素可以生成 "cbad" 。
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/buddy-strings
 */
public class 亲密字符串_859 {

    public static void main(String[] args) {

        String str = "abdefb";
        String str2 = "abedxb";
        System.out.println(buddyStrings(str, str2));

        System.out.println('z' - 'a');
        System.out.println('y' - 'a');
        System.out.println('x' - 'a');

    }

    /**
     * 前提条件：
     * s.length==goal.length，不然怎么交换顺序都不会相等
     * 存在两种情况：
     * s==goal，那么s或者goal字符串中只要存在两个相等字符，那么就是亲密字符串
     * s!=goal，那么s和goal中只有两个索引位置字符不同，其他位置相同，那么就是亲密字符串
     *
     * @param s
     * @param goal
     * @return
     */
    public static boolean buddyStrings(String s, String goal) {
        if (s.length() != goal.length()) {
            return false;
        }
        if (s.equals(goal)) {
            //用来存储某个字符出现的次数，z-a=25，y-a=24，...a-a=0
            int[] count = new int[26];
            for (int i = 0; i < s.length(); i++) {
                count[s.charAt(i) - 'a']++;  //次数+1
                if (count[s.charAt(i) - 'a'] > 1) {
                    return true;
                }
            }
            return false;
        } else {
            //占两个坑
            int first = -1, second = -1;
            for (int i = 0; i < s.length(); i++) {
                if (s.charAt(i) != goal.charAt(i)) {
                    if (first == -1) {  //第一个坑有位置
                        first = i;
                    } else if (second == -1) {  //第二个坑有位置
                        second = i;
                    } else {  //有第三个不同字符，那么不是亲密字符串
                        return false;
                    }
                }
            }
            //第二个坑占了，第一个必然占了
            if (second != -1 && s.charAt(first) == goal.charAt(second) && s.charAt(second) == goal.charAt(first)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 哈希表
     *
     * @param s
     * @param goal
     * @return
     */
    public static boolean efficientBuddyStrings(String s, String goal) {
        if (s.length() != goal.length()) {
            return false;
        }
        if (s.equals(goal)) {
            //用来存储某个字符出现的次数，z-a=25，y-a=24，...a-a=0
            Map<Character, Integer> map = new HashMap<>();
            for (int i = 0; i < s.length(); i++) {
                map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1); //次数+1
                if (map.getOrDefault(s.charAt(i), 0) > 1) {
                    return true;
                }
            }
            return false;
        } else {
            //占两个坑
            int first = -1, second = -1;
            for (int i = 0; i < s.length(); i++) {
                if (s.charAt(i) != goal.charAt(i)) {
                    if (first == -1) {  //第一个坑有位置
                        first = i;
                    } else if (second == -1) {  //第二个坑有位置
                        second = i;
                    } else {  //有第三个不同字符，那么不是亲密字符串
                        return false;
                    }
                }
            }
            //第二个坑占了，第一个必然占了
            if (second != -1 && s.charAt(first) == goal.charAt(second) && s.charAt(second) == goal.charAt(first)) {
                return true;
            }
        }
        return false;
    }

}
